---------------------------------------------------------------------------

-- Company     : EIA / HTA 
-- Author      : Yves Peissard <ypeissard@gmail.com>
-- 
-- Creation Date : 18/04/2009
-- File          : modeSwitcher.vhdl
--
-- Abstract : This is the modeSwitcher of the iTimer project
--            it defines the out going busMode
--			  in function of the inputs
--
--            Inputs: 
--			  alarm      : std_logic, 1 if the alarm is on
--			  			                0 if the alarm is off
--
--			  simplePush : std_logic, 1 if the main button
--									    was pressed for a short time
--
--			  longPush   : std_logic, 1 if the main button
--									  was pressed for a long time
--
--			  clockInput :  std_logic, clock signal
--
--
--			  Output:
--			  busMode    :  std_logic_vector, "00" : Edit mode
--														"01" : Timer mode
--														"10" : Pause mode
--														"11" : Alarm mode
--
---------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;

---------------------------------------------------------------------------
entity modeSwitcher is 
---------------------------------------------------------------------------
port (
	busMode                              : out std_logic_vector(1 downto 0);
	alarm,simplePush,longPush,clockInput : in  std_logic
);
end entity modeSwitcher;


---------------------------------------------------------------------------
architecture modeSwitcher_arch of modeSwitcher is
---------------------------------------------------------------------------

-- type declaration
type state is (state_edit, state_timer, state_pause, state_alarm); 

-- internal signals
signal state_future: state := state_edit;
signal state_present: state := state_edit;
signal old_simplePush: std_logic := '0' ;
signal old_longPush: std_logic := '0' ;
signal old_alarm: std_logic := '0';

begin
	-- chooses the future state
	-- old_alarm, old_simplePush and old_longPush are used here to save
	-- the states of alarm, simplePush and longPush of the
    -- precedent clock cycle
	state_chooser: process (clockInput)
 	begin
      if clockInput'event and clockInput = '1' then
			case state_present is
				-- choose the behavior if we are in edit mode
				when state_edit =>
					if ((old_simplePush = '0' and simplePush = '1') or (old_longPush = '0' and longPush = '1')) then
						state_future <= state_timer;
					end if;
				
				-- choose the behavior if we are in timer mode
				when state_timer =>
					if ((old_simplePush = '0' and simplePush = '1') and (alarm = '0')) then
						state_future <= state_pause;
					elsif ((old_longPush = '0' and longPush = '1') and alarm = '0') then
						state_future <= state_edit;
					elsif (old_alarm = '0' and alarm = '1') then
						state_future <= state_alarm;
					end if;

				-- choose the behavior if we are in pause mode
				when state_pause =>
					if (old_simplePush = '0' and simplePush = '1') then
						state_future <= state_timer;
					elsif (old_longPush = '0' and longPush = '1') then
						state_future <= state_edit;
					end if;
				
				-- choose the behavior if we are in alarm mode
				when state_alarm =>
					if ((old_simplePush = '0' and simplePush = '1') or (old_longPush = '0' and longPush = '1')) then
						state_future <= state_edit;
					end if;
			end case;
			
			case state_present is
				when state_edit =>
					busMode <= "00";
				when state_timer =>
					busMode <= "01";
				when state_pause =>
					busMode <= "10";
				when state_alarm =>
					busMode <= "11";
				when others =>
			end case;

			-- update the old_* variables
			old_simplePush <= simplePush;
			old_longPush <= longPush;
			old_alarm <= alarm;
			
			state_present <= state_future;
		end if;

	end process state_chooser;



    --- Register process ---
	


	--- Output circuit process ---
	-- define busMode

end architecture modeSwitcher_arch;
